package com.noexcs.forum.service;

import com.noexcs.forum.dao.LoginTicketMapper;
import com.noexcs.forum.dao.UserMapper;
import com.noexcs.forum.entity.LoginTicket;
import com.noexcs.forum.entity.User;
import com.noexcs.forum.util.ForumConstant;
import com.noexcs.forum.util.ForumUtil;
import com.noexcs.forum.util.MailClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * todo 添加忘记密码功能
 * @author noexcs
 * @since 5/20/2022 6:14 PM
 */
@Service
public class UserService implements ForumConstant , UserDetailsService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    LoginTicketMapper loginTicketMapper;

    @Value("${forum.path.domain}")
    String domain;

    @Value(("${server.servlet.context-path}"))
    String contextPath;

    @Autowired
    TemplateEngine templateEngine;

    @Autowired
    MailClient mailClient;

    public User findUserById(int id) {
        return userMapper.selectById(id);
    }


    public Map<String, String> register(@NotNull User user) {
        if (user == null) {
            throw new IllegalArgumentException("参数不能为空！");
        }
        HashMap<String, String> map = new HashMap<>();
        if (StringUtils.isBlank(user.getUsername())) {
            map.put("usernameMsg", "账号不能为空!");
            return map;
        }
        if (StringUtils.isBlank(user.getEmail())) {
            map.put("emailMsg", "邮箱不能为空!");
            return map;
        }

        if (StringUtils.isBlank(user.getPassword())) {
            map.put("password", "密码不能为空!");
        }

        if (userMapper.selectByUsername(user.getUsername()) != null) {
            map.put("usernameMsg", "用户名已存在！");
            return map;
        }
        // todo 未验证邮箱是否合法
        if (userMapper.selectByEmail(user.getEmail()) != null) {
            map.put("emailMsg", "该邮箱已被注册！");
            return map;
        }

        String salt = ForumUtil.generateUUID().substring(0, 5);
        user.setSalt(salt);
        user.setPassword(ForumUtil.md5(user.getPassword() + salt));
        user.setType(0);
        user.setActivationCode(ForumUtil.generateUUID());
        user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png", new Random().nextInt(500)));
        user.setCreateTime(new Date());
        userMapper.insertUser(user);

        // 发送激活邮件
        Context context = new Context();
        context.setVariable("email", user.getEmail());
        String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();
        context.setVariable("url", url);
        String content = templateEngine.process("/mail/activation", context);
        mailClient.sendMail(user.getEmail(), "激活账号", content);
        return map;
    }

    public int activation(int userId, String code) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            return ACTIVATION_FAILURE;
        }
        if (user.getStatus() != 0) {
            return ACTIVATION_REPEAT;
        }
        if (!user.getActivationCode().equals(code)) {
            return ACTIVATION_FAILURE;
        }
        userMapper.updateStatus(userId, 1);

        return ACTIVATION_SUCCESS;
    }

    public Map<String, String> login(String username, String password, int expiredSeconds) {
        HashMap<String, String> map = new HashMap<>();

        if (StringUtils.isBlank(username)) {
            map.put("usernameMsg", "账号不能为空!");
            return map;
        }
        if (StringUtils.isBlank(password)) {
            map.put("passwordMsg", "密码不能为空");
            return map;
        }

        User user = userMapper.selectByUsername(username);

        if (user == null) {
            map.put("usernameMsg", "该账号不存在！");
            return map;
        }
        if (user.getStatus() == 0) {
            map.put("usernameMsg", "该账号未激活");
            return map;
        }
        password = ForumUtil.md5(password + user.getSalt());
        if (!user.getPassword().equals(password)) {
            map.put("passwordMsg", "密码错误！");
            return map;
        }

        LoginTicket ticket = new LoginTicket();
        ticket.setUserId(user.getId());
        ticket.setStatus(0);
        ticket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000L));
        ticket.setTicket(ForumUtil.generateUUID());
        loginTicketMapper.insertTicket(ticket);

        map.put("ticket", ticket.getTicket());
        return map;
    }

    public void logout(String ticket) {
        loginTicketMapper.updateStatus(ticket, 1);
    }

    public LoginTicket findLoginTicket(String ticket){
        return loginTicketMapper.selectByTicket(ticket);
    }

    public int updateHeader(int userId,String headerUrl){
        return userMapper.updateHeader(userId,headerUrl);
    }


    public User findUserByName(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return findUserByName(username);
    }
}
